package com.skytech.component.crawler.scratch.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class CrawlerStorageService {
    @Value("${elasticsearch.server}")
    private String server;
    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    private static final Logger log = LoggerFactory.getLogger(CrawlerStorageService.class);

    public JSONObject listYearPolicyNews(String year,String beginTime,String endTime,String catalog,String keyword,Integer pageNo,Integer pageSize,boolean isPage){
        if(pageSize ==null)pageSize = 10;
        if(pageNo == null) pageNo = 1;

        String uri = server+"crawler_storage/storage/_search";

        String base = "{\n" +
                "  \"query\":\n" +
                "  {\n" +
                "    \"bool\": {\n" +
                "      \"must\": [\n" +
                "      ]\n" +
                "    }\n" +
                "  },\n" +
                "  \"sort\":[{\"timestamp\":{\"order\":\"desc\"}}]\n" +
                "}";

        JSONObject json = JSON.parseObject(base);

        JSONArray mustJSONArray = json.getJSONObject("query").getJSONObject("bool").getJSONArray("must");
        if(!StringUtils.isEmpty(catalog)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("catalog",catalog);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(year)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("year",year);
            JSONObject match = new JSONObject();
            match.put("match",jsonObject);
            mustJSONArray.add(match);
        }
        if(!StringUtils.isEmpty(keyword)){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("query",keyword);
            JSONArray jsonArray = new JSONArray();
            jsonArray.add("title");
            jsonArray.add("content");
            jsonObject.put("fields",jsonArray);
            JSONObject must = new JSONObject();
            must.put("multi_match",jsonObject);
            mustJSONArray.add(must);

        }
        JSONObject filter = new JSONObject();
        if(!StringUtils.isEmpty(beginTime)){
            filter.put("gte",beginTime);
        }
        if(!StringUtils.isEmpty(endTime)){
            filter.put("lte",endTime);
        }
        if(!filter.isEmpty()){
            JSONObject timestamp = new JSONObject();
            timestamp.put("timestamp",filter);
            JSONObject range = new JSONObject();
            range.put("range",timestamp);
            json.getJSONObject("query").getJSONObject("bool").put("filter",range);
        }

        if(!isPage){
            pageNo = 1;
            pageSize = 10000;
        }
        json.put("from",(pageNo - 1)*pageSize);
        json.put("size",pageSize);

        ResponseEntity<JSONObject> forEntity = restTemplateBuilder.build().postForEntity(uri,json, JSONObject.class);
        JSONArray jsonArray = forEntity.getBody().getJSONObject("hits").getJSONArray("hits");
        //todo
        transform(jsonArray);

        JSONObject result = new JSONObject();
        result.put("item",transform(jsonArray));
        result.put("total",forEntity.getBody().getJSONObject("hits").getString("total"));
        result.put("pageSize",pageSize);
        result.put("pageNo",pageNo);
        return result;

    }

    public boolean saveData(List<String> sourceIdList,String year){
        try{
            JSONObject forObject = restTemplateBuilder.build().getForObject(server + "crawler_storage/storage/_search?q=year:" + year, JSONObject.class);
            List<String> yearSourceId = new ArrayList<>();
            forObject.getJSONObject("hits").getJSONArray("hits").forEach(o ->{
                yearSourceId.add(((JSONObject)o).getJSONObject("_source").getString("sourceId"));
            });
            for (String sourceId : sourceIdList) {
                JSONObject jsonObject = restTemplateBuilder.build().getForObject(server + "crawler_news/news/" + sourceId, JSONObject.class);
                JSONObject source = jsonObject.getJSONObject("_source");
                if(yearSourceId.contains(jsonObject.getString("_id"))){
                    continue;
                }

                JSONObject policyNews = new JSONObject();
                policyNews.put("sourceId",jsonObject.getString("_id"));
                policyNews.put("title",source.getString("title"));
                policyNews.put("timestamp",source.getString("timestamp"));
                policyNews.put("content",source.getString("content"));
                policyNews.put("catalog",source.getString("catalog"));
                policyNews.put("newsType",source.getString("newsType"));
                policyNews.put("sourceUrl",source.getString("sourceUrl"));
                policyNews.put("year",year);
                //todo save
                restTemplateBuilder.build().postForEntity(server+"crawler_storage/storage/"+ UUID.randomUUID()+"?refresh=true",policyNews,JSONObject.class);
            }
        }catch(Exception e){
            log.error(e.getMessage());
            return false;
        }
        return true;

    }

    public boolean deletePolicy(List<String> ids){
        try{
            for (String id : ids) {
                restTemplateBuilder.build().delete(server+"crawler_storage/storage/"+id+"?refresh=true");
            }
        }catch (Exception e){
            log.error(e.getMessage());
            return false;
        }
        return true;

    }

    private List<JSONObject> transform(JSONArray jsonArray){
        List<JSONObject> list = new ArrayList<>();
        for (Object o : jsonArray) {
            JSONObject jsonObject =  (JSONObject) o;
            JSONObject result = jsonObject.getJSONObject("_source");
            result.put("id",jsonObject.getString("_id"));
            list.add(result);
        }
        return list;

    }
}
